package com.unbox.common.annotation.log;

import com.unbox.common.annotation.Log;
import com.unbox.common.annotation.entity.LogAnntionEntity;
import com.unbox.common.util.UnBoxUtils;
import com.unbox.common.util.UnboxLog;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class UnboxDefaulttLog implements UnboxAnnotationLog{

    UnboxLog log = new UnBoxUtils.LocaleMessageLog(UnboxDefaulttLog.class);

    @Override
    public LogAnntionEntity getLogAnnotation(Object object, String methon, Object[] values) {
        LogAnntionEntity logAnntionEntity = new LogAnntionEntity();
        Class cls = object.getClass();
        logAnntionEntity.setClassName(cls.getName());
        Class[] val = new Class[values.length];
        for(int i = 0; i < val.length; i++) {
            Object obj = values[i];
            if (obj instanceof ArrayList) {
                val[i] = List.class;
            } else if (obj instanceof HashMap) {
                val[i] = Map.class;
            } else {
                val[i] = obj.getClass();
            }
        }
        try {
             Method method = cls.getMethod(methon, val);
             Log log = method.getAnnotation(Log.class);
             if (log != null) {
                 logAnntionEntity.setName(log.name());
             }
             Class[] clsBaseInterface = cls.getInterfaces();
             for(Class objCls: clsBaseInterface) {
                Method method1 = objCls.getMethod(methon, val);
                FeignClient feignClient = (FeignClient) objCls.getAnnotation(FeignClient.class);
                if (feignClient != null) {
                    logAnntionEntity.setServiceName(feignClient.value());
                }
                if (method1 != null) {
                    RequestMapping requestMapping = method1.getAnnotation(RequestMapping.class);
                    if (requestMapping != null) {
                        logAnntionEntity.setPath(requestMapping.value()[0]);
                    }
                    PostMapping postMapping = method1.getAnnotation(PostMapping.class);
                    if (postMapping != null) {
                        logAnntionEntity.setPath(postMapping.value()[0]);
                    }
                    GetMapping getMapping = method1.getAnnotation(GetMapping.class);
                    if (getMapping != null) {
                        logAnntionEntity.setPath(getMapping.value()[0]);
                    }
                    PutMapping putMapping = method1.getAnnotation(PutMapping.class);
                    if (putMapping != null) {
                        logAnntionEntity.setPath(putMapping.value()[0]);
                    }
                    DeleteMapping deleteMapping = method1.getAnnotation(DeleteMapping.class);
                    if (deleteMapping != null) {
                        logAnntionEntity.setPath(deleteMapping.value()[0]);
                    }
                }
             }

             RequestMapping requestMapping = method.getAnnotation(RequestMapping.class);
             if (requestMapping != null) {
                 logAnntionEntity.setPath(requestMapping.value()[0]);
             }
             PostMapping postMapping = method.getAnnotation(PostMapping.class);
             if (postMapping != null) {
                 logAnntionEntity.setPath(postMapping.value()[0]);
             }
             GetMapping getMapping = method.getAnnotation(GetMapping.class);
             if (getMapping != null) {
                logAnntionEntity.setPath(getMapping.value()[0]);
             }
             PutMapping putMapping = method.getAnnotation(PutMapping.class);
             if (putMapping != null) {
                logAnntionEntity.setPath(putMapping.value()[0]);
             }
             DeleteMapping deleteMapping = method.getAnnotation(DeleteMapping.class);
             if (deleteMapping != null) {
                logAnntionEntity.setPath(deleteMapping.value()[0]);
             }
             return logAnntionEntity;
        } catch (NoSuchMethodException e) {
            log.error("log.hanser.annotation.error.message", e.getMessage());
        }
        return null;
    }
}
